<?php
namespace Amis\dataviewer;

use Amis\Basics\AmisBasics;

class CRUD extends AmisBasics
{
    public string $type = 'crud';
    public string $className;
    public array  $columns;

    public function columns(TableColumns ...$columns)
    {
        $this->set(__FUNCTION__,...$columns);
        return $this;
    }

    public function className($className)
    {
        $this->className = $className;
        return $this;
    }

    public string $mode;

    /**
     * "table" 、 "cards" 或者 "list"
     * @param string $mode
     * @return $this
     */
    public function mode(string $mode = 'table')
    {
        if (in_array($mode, ['table', 'cards', 'list']))
            $this->mode = $mode;
        return $this;
    }

    public string $title;

    /**
     * 可设置成空，当设置成空时，没有标题栏
     * @param string $title
     * @return $this
     */
    public function title(string $title = '')
    {
        $this->title = $title;
        return $this;
    }

    public string $api;

    /**
     * CRUD 用来获取列表数据的 api。
     * @param string $api
     * @return $this
     */
    public function api(string $api)
    {
        $this->api = $api;
        return $this;
    }

    public bool $loadDataOnce;

    /**
     * 是否一次性加载所有数据（前端分页）
     * @param bool $loadDataOnce
     * @return $this
     */
    public function loadDataOnce(bool $loadDataOnce)
    {
        $this->loadDataOnce = $loadDataOnce;
        return $this;
    }

    public bool $loadDataOnceFetchOnFilter;

    /**
     * 在开启 loadDataOnce 时，filter 时是否去重新请求 api
     * @param bool $loadDataOnceFetchOnFilter
     * @return $this
     */
    public function loadDataOnceFetchOnFilter(bool $loadDataOnceFetchOnFilter = true)
    {
        $this->loadDataOnceFetchOnFilter = $loadDataOnceFetchOnFilter;
        return $this;
    }

    public string $source;

    /**
     * 数据映射接口返回某字段的值，不设置会默认使用接口返回的${items}或者${rows}，也可以设置成上层数据源的内容
     * @param string $source
     * @return $this
     */
    public function source(string $source)
    {
        $this->source = $source;
        return $this;
    }

    public CrudFilter $filter;

    /**
     * 设置过滤器，当该表单提交后，会把数据带给当前 mode 刷新列表。
     * @param CrudFilter $filter
     * @return $this
     */
    public function filter(CrudFilter $filter)
    {
        $this->filter = $filter;
        return $this;
    }

    public bool $filterTogglable;

    /**
     * 是否可显隐过滤器
     * @param bool $filterTogglable
     * @return $this
     */
    public function filterTogglable(bool $filterTogglable = false)
    {
        $this->filterTogglable = $filterTogglable;
        return $this;
    }

    public bool $filterDefaultVisible;

    /**
     * 设置过滤器默认是否可见。
     * @param bool $filterDefaultVisible
     * @return $this
     */
    public function filterDefaultVisible(bool $filterDefaultVisible = true)
    {
        $this->filterDefaultVisible = $filterDefaultVisible;
        return $this;
    }

    public bool $initFetch;

    /**
     * 是否初始化的时候拉取数据, 只针对有 filter 的情况, 没有 filter 初始都会拉取数据
     * @param bool $initFetch
     * @return $this
     */
    public function initFetch(bool $initFetch = true)
    {
        $this->initFetch = $initFetch;
        return $this;
    }

    public int $interval;

    /***
     * 刷新时间(最低 1000)
     * @param int $interval
     * @return $this
     */
    public function interval(int $interval = 3000)
    {
        $this->interval = $interval;
        return $this;
    }

    public bool $silentPolling;

    /**
     * 配置刷新时是否隐藏加载动画
     * @param bool $silentPolling
     * @return $this
     */
    public function silentPolling(bool $silentPolling = false)
    {
        $this->silentPolling = $silentPolling;
        return $this;
    }

    public string $stopAutoRefreshWhen;

    /**
     * 通过表达式来配置停止刷新的条件
     * @param string $stopAutoRefreshWhen
     * @return $this
     */
    public function stopAutoRefreshWhen(string $stopAutoRefreshWhen = '')
    {
        $this->stopAutoRefreshWhen = $stopAutoRefreshWhen;
        return $this;
    }

    public bool $stopAutoRefreshWhenModalIsOpen;

    /**
     * 是否将过滤条件的参数同步到地址栏
     * @param bool $stopAutoRefreshWhenModalIsOpen
     * @return $this
     */
    public function stopAutoRefreshWhenModalIsOpen(bool $stopAutoRefreshWhenModalIsOpen = false)
    {
        $this->stopAutoRefreshWhenModalIsOpen = $stopAutoRefreshWhenModalIsOpen;
        return $this;
    }

    public bool $syncLocation;

    /**
     * 是否将过滤条件的参数同步到地址栏
     * @param bool $syncLocation
     * @return $this
     */
    public function syncLocation(bool $syncLocation = true)
    {
        $this->syncLocation = $syncLocation;
        return $this;
    }

    public bool $draggable;

    /**
     * 是否可通过拖拽排序
     * @param bool $draggable
     * @return $this
     */
    public function draggable(bool $draggable = false)
    {
        $this->draggable = $draggable;
        return $this;
    }

    public bool $resizable;

    /**
     * 是否可以调整列宽度
     * @param bool $resizable
     * @return $this
     */
    public function resizable(bool $resizable = true)
    {
        $this->resizable = $resizable;
        return $this;
    }

    public bool $itemDraggableOn;

    /**
     * 用表达式来配置是否可拖拽排序
     * @param bool $itemDraggableOn
     * @return $this
     */
    public function itemDraggableOn(bool $itemDraggableOn)
    {
        $this->itemDraggableOn = $itemDraggableOn;
        return $this;
    }

    /**
     * 保存排序的 api。
     * @param string $saveOrderApi
     * @return $this
     */
    public function saveOrderApi(string $saveOrderApi)
    {
        $this->saveOrderApi = $saveOrderApi;
        return $this;
    }

    /**
     * 快速编辑后用来批量保存的 API。
     * @param string $quickSaveApi
     * @return $this
     */
    public function quickSaveApi(string $quickSaveApi)
    {
        $this->quickSaveApi = $quickSaveApi;
        return $this;
    }

    /**
     * 快速编辑配置成及时保存时使用的 API。
     * @param string $quickSaveItemApi
     * @return $this
     */
    public function quickSaveItemApi(string $quickSaveItemApi)
    {
        $this->quickSaveItemApi = $quickSaveItemApi;
        return $this;
    }

    /**
     * 批量操作列表，配置后，表格可进行选中操作。
     * @param array $bulkActions
     * @return $this
     */
    public function bulkActions(array $bulkActions)
    {
        $this->bulkActions = $bulkActions;
        return $this;
    }

    /**
     * @param \Amis\dataviewer\CRUDMessages $messages
     * @return \Amis\dataviewer\CRUDMessages
     */
    public function messages(CRUDMessages $messages)
    {
        return $this->messages = $messages;
    }

    /**
     * 设置 ID 字段名。
     * @param string $primaryField
     * @return $this
     */
    public function primaryField(string $primaryField = 'id')
    {
        $this->primaryField = $primaryField;
        return $this;
    }

    /**
     * 设置一页显示多少条数据。
     * @param int $perPage
     * @return $this
     */
    public function perPage(int $perPage = 10)
    {
        $this->perPage = $perPage;
        return $this;
    }

    /**
     * 默认排序字段，这个是传给后端，需要后端接口实现
     * @param string $orderBy
     * @return $this
     */
    public function orderBy(string $orderBy)
    {
        $this->orderBy = $orderBy;
        return $this;
    }

    /**
     * 排序方向
     * @param bool $IsAsc
     * @return $this
     */
    public function orderDir(bool $IsAsc = true)
    {
        $this->orderDir = $IsAsc ? 'asc' : 'desc';
        return $this;
    }

    /**
     * 设置默认 filter 默认参数，会在查询的时候一起发给后端
     * @param array $defaultParams
     * @return $this
     */
    public function defaultParams(array $defaultParams)
    {
        $this->defaultParams = $defaultParams;
        return $this;
    }

    /**
     * 设置分页页码字段名。
     * @param string $pageField
     * @return $this
     */
    public function pageField(string $pageField = 'page')
    {
        $this->pageField = $pageField;
        return $this;
    }

    /**
     * 设置分页一页显示的多少条数据的字段名。注意：最好与 defaultParams 一起使用，请看下面例子。
     * @param string $perPageField
     * @return $this
     */
    public function perPageField(string $perPageField = 'perPage')
    {
        $this->perPageField = $perPageField;
        return $this;
    }

    /**
     * 设置一页显示多少条数据下拉框可选条数。
     * @param array|int[] $perPageAvailable
     * @return $this
     */
    public function perPageAvailable(array $perPageAvailable = [5, 10, 20, 50, 100])
    {
        $this->perPageAvailable = $perPageAvailable;
        return $this;
    }

    /**
     * 设置用来确定位置的字段名，设置后新的顺序将被赋值到该字段中。
     * @param string $orderField
     * @return $this
     */
    public function orderField(string $orderField)
    {
        $this->orderField = $orderField;
        return $this;
    }

    /**
     * 隐藏顶部快速保存提示
     * @param bool $hideQuickSaveBtn
     * @return $this
     */
    public function hideQuickSaveBtn(bool $hideQuickSaveBtn = false)
    {
        $this->hideQuickSaveBtn = $hideQuickSaveBtn;
        return $this;
    }

    /**
     * 当切分页的时候，是否自动跳顶部。
     * @param bool $autoJumpToTopOnPagerChange
     * @return $this
     */
    public function autoJumpToTopOnPagerChange(bool $autoJumpToTopOnPagerChange = false)
    {
        $this->autoJumpToTopOnPagerChange = $autoJumpToTopOnPagerChange;
        return $this;
    }

    /**
     * 将返回数据同步到过滤器上。
     * @param bool $syncResponse2Query
     * @return $this
     */
    public function syncResponse2Query(bool $syncResponse2Query = true)
    {
        $this->syncResponse2Query = $syncResponse2Query;
        return $this;
    }

    /**
     * 保留条目选择，默认分页、搜素后，用户选择条目会被清空，开启此选项后会保留用户选择，可以实现跨页面批量操作。
     * @param bool $keepItemSelectionOnPageChange
     * @return $this
     */
    public function keepItemSelectionOnPageChange(bool $keepItemSelectionOnPageChange = true)
    {
        $this->keepItemSelectionOnPageChange = $keepItemSelectionOnPageChange;
        return $this;
    }

    /**
     * 单条描述模板，keepItemSelectionOnPageChange设置为true后会把所有已选择条目列出来，此选项可以用来定制条目展示文案。
     * @param string $labelTpl
     * @return $this
     */
    public function labelTpl(string $labelTpl)
    {
        $this->labelTpl = $labelTpl;
        return $this;
    }

    /**
     * 顶部工具栏配置
     * @param array|string[] $headerToolbar
     * @return $this
     */
    public function headerToolbar(array $headerToolbar = ['bulkActions', 'pagination'])
    {
        $this->headerToolbar = $headerToolbar;
        return $this;
    }

    /**
     * 底部工具栏配置
     * @param array|string[] $footerToolbar
     * @return $this
     */
    public function footerToolbar(array $footerToolbar = ['statistics', 'pagination'])
    {
        $this->footerToolbar = $footerToolbar;
        return $this;
    }

    /**
     * 是否总是显示分页
     * @param bool $alwaysShowPagination
     * @return $this
     */
    public function alwaysShowPagination(bool $alwaysShowPagination = false)
    {
        $this->alwaysShowPagination = $alwaysShowPagination;
        return $this;
    }

    /**
     * 是否固定表头(table 下)
     * @param bool $affixHeader
     * @return $this
     */
    public function affixHeader(bool $affixHeader = true)
    {
        $this->affixHeader = $affixHeader;
        return $this;
    }

    /**
     * 是否开启查询区域，开启后会根据列元素的 searchable 属性值，自动生成查询条件表单
     * @param bool $autoGenerateFilter
     * @return $this
     */
    public function autoGenerateFilter(bool $autoGenerateFilter = false)
    {
        $this->autoGenerateFilter = $autoGenerateFilter;
        return $this;
    }
}